package com.example.administrator.demorecyclerview.auto_viewpager;

import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.support.v4.view.AbsSavedState;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by Administrator on 2017/12/5.
 */

public class EmptyRecyclerView extends RecyclerView {
    View mEmptyView;
    View mErrorView;

    public EmptyRecyclerView(Context context) {
        super(context);
    }

    public EmptyRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public EmptyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        SavedState savedState = new SavedState(super.onSaveInstanceState());
        savedState.emptyVisible = isEmptyViewVisible();
        savedState.errorVisible = isErrorViewVisible();
        return savedState;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());
        final SavedState savedState = (SavedState) state;
        if (savedState.emptyVisible)
            showEmptyView();
        else
            hideEmptyView();

        if (savedState.errorVisible)
            showErrorView();
        else
            hideErrorView();


    }


    private static class SavedState extends AbsSavedState {
        boolean emptyVisible;
        boolean errorVisible;

        public SavedState(Parcel source, ClassLoader loader) {
            super(source, loader);
            emptyVisible = source.readByte() != 0;
            errorVisible = source.readByte() != 0;
        }

        SavedState(Parcelable superState) {
            super(superState);
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeByte((byte) (emptyVisible ? 1 : 0));
            dest.writeByte((byte) (errorVisible ? 1 : 0));
        }


        public static final Creator<SavedState> CREATOR = new ClassLoaderCreator<SavedState>() {
            @Override
            public SavedState createFromParcel(Parcel in, ClassLoader loader) {
                return new SavedState(in, loader);
            }

            @Override
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in, null);
            }

            @Override
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };


    }


    public void setEmptyView(View view, boolean checkIsEmpty) {
        mEmptyView = view;
        if (checkIsEmpty) {
            checkIsEmpty();
        }
    }

    public void setErrorView(View view, boolean checkIsError) {
        mErrorView = view;
        if (checkIsError) {
            checkIsError();
        }
    }

    public View getEmptyView() {
        return mEmptyView;
    }


    public EmptyRecyclerView setEmptyView(View view) {
        setEmptyView(view, false);
        return this;
    }

    public EmptyRecyclerView setErrorView(View view) {
        setErrorView(view, false);
        return this;
    }

    @Override
    public void setAdapter(Adapter adapter) {
        setAdapter(adapter, false, false);
    }

    void setAdapter(Adapter adapter, boolean checkIsEmpty) {
        final Adapter old = super.getAdapter();
        if (old != null) {
            old.unregisterAdapterDataObserver(observer);
        }
        super.setAdapter(adapter);
        if (adapter != null) {
            adapter.registerAdapterDataObserver(observer);
        }
        if (checkIsEmpty) {
            checkIsEmpty();
        }
    }

    void setAdapter(Adapter adapter, boolean checkIsEmpty, boolean checkIsError) {
        final Adapter old = super.getAdapter();
        if (old != null) {
            old.unregisterAdapterDataObserver(observer);
        }
        super.setAdapter(adapter);
        if (adapter != null) {
            adapter.registerAdapterDataObserver(observer);
        }
        if (checkIsEmpty) {
            checkIsEmpty();
        }

        if (checkIsError) {
            checkIsError();
        }
    }


    final private AdapterDataObserver observer = new AdapterDataObserver() {
        @Override
        public void onChanged() {
            checkIsEmpty();
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            checkIsEmpty();
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            checkIsEmpty();
        }
    };

    boolean checkIsEmpty() {
        final Adapter adapter = super.getAdapter();
        if (adapter != null && adapter.getItemCount() > 0) {
            hideEmptyView();
            return false;
        } else {
            showEmptyView();
            return true;
        }
    }


    boolean checkIsError() {
        final Adapter adapter = super.getAdapter();
        if (adapter != null && adapter.getItemCount() > 0) {
            hideEmptyView();
            return false;
        } else {
            showEmptyView();
            return true;
        }
    }

    public void hideEmptyView() {
        final View enpty = mEmptyView;
        if (enpty != null && enpty.getVisibility() != INVISIBLE) {
            enpty.setVisibility(INVISIBLE);
        }
    }

    public void showEmptyView() {
        final View enpty = mEmptyView;
        if (enpty != null && enpty.getVisibility() != VISIBLE) {
            enpty.setVisibility(VISIBLE);
        }
    }

    public boolean isEmptyViewVisible() {
        final View enpty = mEmptyView;
        return enpty != null && enpty.getVisibility() == VISIBLE;
    }

    public void showErrorView() {
        final View errorView = mErrorView;
        if (errorView != null && errorView.getVisibility() != VISIBLE) {
            errorView.setVisibility(VISIBLE);
        }
    }

    public void hideErrorView() {
        final View errorView = mErrorView;
        if (errorView != null && errorView.getVisibility() != INVISIBLE) {
            errorView.setVisibility(INVISIBLE);
        }
    }

    public boolean isErrorViewVisible() {
        final View errorView = mErrorView;
        return errorView != null && errorView.getVisibility() == VISIBLE;
    }
}
